package com.sunwayworld.basemodule.common.eptstorage.acqconfig.service.impl;

import com.sunwayworld.cloud.module.equipt.fileacq.CoreEquiptFileAcqService;
import com.sunwayworld.cloud.module.equipt.record.bean.CoreEquiptAcqRecordBean;
import com.sunwayworld.cloud.module.equipt.record.service.CoreEquiptAcqRecordService;
import com.sunwayworld.framework.constant.Constant;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.context.concurrent.GikamConcurrentLocker;
import com.sunwayworld.framework.executor.ExecutorHelper;
import com.sunwayworld.framework.i18n.I18nHelper;
import com.sunwayworld.framework.io.file.FileScope;
import com.sunwayworld.framework.utils.FileUtils;
import com.sunwayworld.framework.utils.ObjectUtils;
import com.sunwayworld.framework.utils.StringUtils;
import com.sunwayworld.module.item.file.bean.CoreFileBean;
import com.sunwayworld.module.item.file.service.CoreFileService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Profile;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * 文件采集扫描service
 */
@Repository
@Profile({ "lims-file-acq" })
public class LimsEquiptFileAcqSchedule {
    private static final Logger logger = LogManager.getLogger(LimsEquiptFileAcqSchedule.class);
    private List<CoreEquiptAcqRecordBean> noneAcqRecordList = null;

    public LimsEquiptFileAcqSchedule() {
    }

    @Transactional
    @Scheduled(fixedDelay = 30000L)
    public void fileAcqSchedule() {
        GikamConcurrentLocker.isolatedRun("CORE_FILE_ACQ_INSERTRECORD_LOOP_RUNNER", () -> {
            this.insertAcqRecord();
        });
        this.fileAcq();
    }

    //扫描文件-》文件生成一个 CoreEquiptAcqRecordBean-> 插入CoreEquiptAcqRecordBean -> 上传文件到CoreEquiptAcqRecordBean
    private void insertAcqRecord() {
    	CoreEquiptAcqRecordService equiptAcqRecordService = (CoreEquiptAcqRecordService) ApplicationContextHelper.getBean(CoreEquiptAcqRecordService.class);
        String equiptAcqRecordTable = equiptAcqRecordService.getDao().getTable();
        CoreFileService fileService = (CoreFileService) ApplicationContextHelper.getBean(CoreFileService.class);
        CoreEquiptFileAcqService equiptFileAcqService = (CoreEquiptFileAcqService) ApplicationContextHelper.getBean(CoreEquiptFileAcqService.class);
        String fileAcqdir = ApplicationContextHelper.getEnvironment().getProperty("sunway.config.equipt.file.acq.path");
        logger.info("fileAcqSchedule,fileAcqdir={}",fileAcqdir);
        if (!StringUtils.isEmpty(fileAcqdir)) {
            Path fileAcqPath = Paths.get(fileAcqdir);
            if (Files.isDirectory(fileAcqPath, new LinkOption[0])) {
                List<CoreEquiptAcqRecordBean> insertAcqRecordList = new ArrayList();
                List<File> fileList = FileUtils.getFileList(fileAcqPath);
                fileList.forEach((file) -> {
                    CoreEquiptAcqRecordBean fileAcq = new CoreEquiptAcqRecordBean();
                    fileAcq.setId(ApplicationContextHelper.getNextIdentity());
                    fileAcq.setAcqCategory("file");
                    fileAcq.setFilePath(file.getAbsolutePath());
                    fileAcq.setFileName(file.getName());
                    fileAcq.setCreatedById("SYSTEM");
                    try {
                        logger.info("fileAcqSchedule,开始解析文件file={}",file);
                        fileAcq.setAcqRawData(equiptFileAcqService.extractTextFromFile(file));
                        fileAcq.setAcqResult(Constant.NO);
                        equiptFileAcqService.preAcqRecordInserted(fileAcq, file);
                    } catch (Throwable var8) {
                        logger.error(file.getName() + I18nHelper.getMessage("CORE.MODULE.EQUIPT.FILE.ACQ.EXCEPTION.FILE_READ_FAIL", new String[0]) + var8.getMessage());
                        fileAcq.setMessage(ObjectUtils.getStackTrace(var8));
                        fileAcq.setAcqResult("-1");
                    }

                    try {
                        CoreFileBean coreFile = new CoreFileBean();
                        coreFile.setTargetId(equiptAcqRecordTable + "$" + fileAcq.getId());
                        coreFile.setScope(FileScope.equipt.name());
                        fileService.upload(coreFile, file);
                        insertAcqRecordList.add(fileAcq);
                    } catch (Exception var7) {
                        logger.error(file.getName() + I18nHelper.getMessage("CORE.MODULE.EQUIPT.FILE.ACQ.EXCEPTION.ARCHIVE", new String[0]) + var7.getMessage());
                    }

                });
                if (!insertAcqRecordList.isEmpty()) {
                    equiptAcqRecordService.insertInNewTransaction(insertAcqRecordList);
                }

            }
        }
    }

    private void fileAcq() {
        CoreEquiptAcqRecordService equiptAcqRecordService = (CoreEquiptAcqRecordService) ApplicationContextHelper.getBean(CoreEquiptAcqRecordService.class);
        CoreEquiptFileAcqService equiptFileAcqService = (CoreEquiptFileAcqService) ApplicationContextHelper.getBean(CoreEquiptFileAcqService.class);
        this.noneAcqRecordList = equiptAcqRecordService.selectNoneAcqRecordList();
        if (!this.noneAcqRecordList.isEmpty()) {
            this.noneAcqRecordList.forEach((r) -> {
                ExecutorHelper.submit(() -> {
                    Long recordId = r.getId();
                    GikamConcurrentLocker.isolatedRun("CORE_FILE_ACQ_LOOP_RUNNER_" + recordId, () -> {
                        if ("0".equals(((CoreEquiptAcqRecordBean) equiptAcqRecordService.selectById(recordId)).getAcqResult())) {
                            try {
                                equiptFileAcqService.fileAcq(r);
                                r.setAcqResult("1");
                            } catch (Throwable var5) {
                                logger.error(var5.getMessage());
                                r.setMessage(ObjectUtils.getStackTrace(var5));
                                r.setAcqResult("-1");
                            }

                            equiptAcqRecordService.updateIfChangedInNewTransaction(r);
                        }
                    });
                });
            });
            this.noneAcqRecordList = null;
        }
    }
}
